'use strict';
var vk; // 全局vk实例
// 涉及的表名
const dbName = require("../../../dao/config.js");

var db = uniCloud.database(); // 全局数据库引用
var _ = db.command; // 数据库操作符
var $ = _.aggregate; // 聚合查询操作符
/**
 * 权限注意：访问以下链接查看
 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#内置权限
 */
var cloudObject = {
	isCloudObject: true, // 标记为云对象模式
	/**
	 * 请求前处理，主要用于调用方法之前进行预处理，一般用于拦截器、统一的身份验证、参数校验、定义全局对象等。
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#before-预处理
	 */
	_before: async function() {
		vk = this.vk; // 将vk定义为全局对象
		// let { customUtil, uniID, config, pubFun } = this.getUtil(); // 获取工具包
	},
	/**
	 * 请求后处理，主要用于处理本次调用方法的返回结果或者抛出的错误
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#after-后处理
	 */
	_after: async function(options) {
		let { err, res } = options;
		if (err) {
			return; // 如果方法抛出错误，直接return;不处理
		}
		return res;
	},
	/**
	 * 获取列表
	 * @url admin/business/sys.goods.getList 前端调用的url参数地址
	 */
	getList: async function(data) {
		let res = { code: 0, msg: '' };
		let { uid } = this.getClientInfo(); // 获取客户端信息
		// 业务逻辑开始-----------------------------------------------------------
		let {
			formData = {}
		} = data;
		let {
			status,
			category_ids
		} = formData;
		let whereJson = {};
		if (status === 0) {
			// 上架
			whereJson["status"] = 1;
			whereJson["is_on_sale"] = true;
		} else if (status === 1) {
			// 下架
			whereJson["status"] = 1;
			whereJson["is_on_sale"] = false;
		} else if (status === 2) {
			// 已删除
			whereJson["status"] = 2;
		} else if (status === 3) {
			// 已售罄
			whereJson["status"] = 1;
			whereJson["stock"] = _.lte(0);
		}
		if (category_ids) {
			// 带出子分类
			formData.category_ids = await vk.daoCenter.categoryDao.getCategoryIdsByIds(category_ids);
		}
		res = await vk.daoCenter.goodsDao.getTableData({
			data,
			whereJson,
			// 副表列表
			foreignDB: [{
				dbName: dbName.category,
				localKey: "category_ids",
				localKeyType: "array",
				foreignKey: "_id",
				as: "categoryList",
				limit: 100
			}]
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 删除（商品进入回收站）
	 * 因为商品可能涉及历史订单，奖励，业绩等等，故只能软删除，禁止直接从数据库中删除。
	 * @url admin/business/sys.goods.delete 前端调用的url参数地址
	 */
	delete: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			ids, // 商品id数组
			mode = 1, // 1 进入回收站 2 从回收站中删除
		} = data;
		let time = Date.now();
		if (vk.pubfn.isNull(ids)) {
			return { code: -1, msg: '参数错误' };
		}
		if (!vk.pubfn.isArray(ids)) {
			return { code: -1, msg: 'ids必须是数组' };
		}
		if (mode === 1) {
			res.num = await vk.daoCenter.goodsDao.update({
				whereJson: {
					_id: _.in(ids),
					status: 1
				},
				dataJson: {
					status: 2, // 1 正常 2 已删除（回收站） 3 已删除（不在回收站）
					delete_time: time
				}
			});
		} else if (mode === 2) {
			res.num = await vk.daoCenter.goodsDao.update({
				whereJson: {
					_id: _.in(ids),
					status: 2
				},
				dataJson: {
					status: 3, // 1 正常 2 已删除（回收站） 3 已删除（不在回收站）
					delete_time: time
				}
			});
		}
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 恢复（商品从回收站中找回）
	 * 因为商品可能涉及历史订单，奖励，业绩等等，故只能软删除，禁止直接从数据库中删除。
	 * @url admin/business/sys.goods.recovery 前端调用的url参数地址
	 */
	recovery: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			ids, // 商品id数组
		} = data;
		let time = Date.now();
		if (vk.pubfn.isNull(ids)) {
			return { code: -1, msg: '参数错误' };
		}
		if (!vk.pubfn.isArray(ids)) {
			return { code: -1, msg: 'ids必须是数组' };
		}
		res.num = await vk.daoCenter.goodsDao.update({
			whereJson: {
				_id: _.in(ids),
				status: 2
			},
			dataJson: {
				status: 1, // 1 正常 2 已删除（回收站） 3 已删除（不在回收站）
				delete_time: _.remove()
			}
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改商品上架状态
	 * @url admin/business/sys.goods.updateIsOnSale 前端调用的url参数地址
	 */
	updateIsOnSale: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			ids, // 商品id数组
			is_on_sale, // true 上架 false 下架
		} = data;
		if (vk.pubfn.isNullOne(ids, is_on_sale)) {
			return { code: -1, msg: '参数错误' };
		}
		if (!vk.pubfn.isArray(ids)) {
			return { code: -1, msg: 'ids必须是数组' };
		}
		res.num = await vk.daoCenter.goodsDao.update({
			whereJson: {
				_id: _.in(ids)
			},
			dataJson: {
				is_on_sale
			}
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改商品sku库存
	 * @url admin/business/sys.goods.updateGoodsSkuStock 前端调用的url参数地址
	 */
	updateGoodsSkuStock: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			sku_list
		} = data;
		if (vk.pubfn.isNullOne(sku_list)) {
			return { code: -1, msg: '参数错误' }
		}
		let goodsIds = [];
		for (let i = 0; i < sku_list.length; i++) {
			let item = sku_list[i];
			// 执行数据库API请求
			let stock;
			// 库存
			if (vk.pubfn.isNotNull(item.stock) && item.stock >= 0) {
				stock = Number(item.stock);
				goodsIds.push(item.goods_id);
				// 更新sku库存
				await vk.daoCenter.skuDao.updateById(item._id, {
					stock
				});
			}
		}
		// 去除重复
		goodsIds = [...new Set(goodsIds)];
		// 更新商品总库存
		for (let i = 0; i < goodsIds.length; i++) {
			let goods_id = goodsIds[i];
			let stock = await vk.daoCenter.skuDao.sum({
				fieldName: "stock",
				whereJson: {
					goods_id
				}
			});
			await vk.daoCenter.goodsDao.updateById({
				id: goods_id,
				dataJson: {
					stock
				}
			});
		}
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改商品sku信息
	 * @url admin/business/sys.goods.updateGoodsSku 前端调用的url参数地址
	 */
	updateGoodsSku: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			sku_list
		} = data;
		if (vk.pubfn.isNullOne(sku_list)) {
			return { code: -1, msg: '参数错误' }
		}
		for (let i = 0; i < sku_list.length; i++) {
			let item = sku_list[i];
			// 执行数据库API请求
			let dataJson = {};
			// 价格
			if (vk.pubfn.isNotNull(item.price) && item.price >= 0) {
				dataJson.price = Number(item.price);
			}
			// 市场价
			if (vk.pubfn.isNotNull(item.market_price) && item.market_price >= 0) {
				dataJson.market_price = Number(item.market_price);
			}
			await vk.daoCenter.skuDao.updateById(item._id, dataJson);
		}
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},

	/**
	 * 修改商品排序
	 * @url admin/business/sys.goods.updateGoodsSort 前端调用的url参数地址
	 */
	updateGoodsSort: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 商品id
			sort,
		} = data;
		if (vk.pubfn.isNullOne(_id, sort)) {
			return { code: -1, msg: '参数错误' };
		}
		if (isNaN(sort)) {
			return { code: -1, msg: 'sort必须是数字' };
		}
		await vk.daoCenter.goodsDao.updateById({
			id: _id,
			dataJson: {
				sort: Number(sort)
			}
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改商品基础信息
	 * @url admin/business/sys.goods.updateGoodsBaseInfo 前端调用的url参数地址
	 */
	updateGoodsBaseInfo: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 商品id
		} = data;
		if (vk.pubfn.isNull(_id)) return { code: -1, msg: "id不能为空" };
		let dataJson = {};
		let arr = ["name", "keywords", "is_new", "is_best", "is_hot", "disable_vip", "disable_coupon"];
		arr.map((key, index) => {
			if (vk.pubfn.isNotNull(data[key])) dataJson[key] = data[key];
		});
		await vk.daoCenter.goodsDao.updateById({
			id: _id,
			dataJson
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 获取商品信息
	 * @url admin/business/sys.goods.pub_findGoodsInfo 前端调用的url参数地址
	 */
	pub_findGoodsInfo: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id,
		} = data;
		res.info = await vk.daoCenter.goodsDao.findByIdHaveSkuList(_id);
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 添加或修改商品信息
	 * @url admin/business/sys.goods.addUpdate 前端调用的url参数地址
	 */
	addUpdate: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			mode, // add 添加 update 修改
			_id, // ID
			// 基础信息
			type, // 0 实物商品（需物流） 1 电子卡券（无需物流）
			name,
			category_ids,
			goods_desc,
			keywords,
			// 图片信息
			goods_thumb,
			goods_banner_imgs,
			// 详情信息
			goods_detail_mode,
			goods_detail_imgs,
			goods_detail_body,
			goods_tags,
			goods_services,
			// 实物商品
			is_free_delivery,
			freight_id,
			// 电子卡券
			exp_time_mode,
			exp_time_range,
			exp_time_rule,
			// 多规格信息
			spec_list, // sku规则组
			// 商品参数信息
			is_on_sale = true,
			is_new = true,
			is_best,
			is_hot,
			disable_vip, // 是否禁用会员价
			disable_coupon, // 是否禁用优惠券
			// 购物车规则
			cart_rule, // 购物车规则
			// 商品限购规则
			limit_buy_rule, // 商品限购规则
			// 其他信息
			initial_sell_count = 0, // 商品初始总销量
			seller_note,
			sort = 0,
			// 积分规则
			integral_rule,
			// 其他字段
			sku_list, // sku表,需保存到sku表里
			// 分销专属字段
			reward_rule, // 商品奖励单独规则
		} = data;
		let status = 1;
		if (vk.pubfn.isNullOne(mode, spec_list, sku_list, name)) {
			return { code: -1, msg: "商品参数错误" };
		}
		let stock = 0; // 商品总库存数量（所有sku的库存加起来的数量）
		// 检查sku内的参数是否正确
		for (let i in sku_list) {
			let sku = sku_list[i];
			let { sku_name_arr, price, stock: skuStock, weight } = sku;
			if (vk.pubfn.isNullOne(sku_name_arr, price, skuStock, weight)) {
				return { code: -1, msg: "SKU参数错误（价格、库存、重量为必填字段）" };
			}
			stock += skuStock;
		}
		let countWhereJson = {
			name,
			status: _.in([0, 1, 2])
		};
		if (mode === "update") {
			// 如果是修改，则需要再判断下_id是否存在
			if (vk.pubfn.isNullOne(_id)) {
				return { code: -1, msg: "商品ID不能为空" };
			}
			// 同时，在查询商品名称是否重复时排除自己
			countWhereJson["_id"] = _.neq(_id);
		}
		let time = Date.now();
		let real_sell_count = 0; // 商品实际总销量（商家看到的）
		let comment_count = 0; // 累计评价数
		let view_count = 0; // 累计浏览量
		let on_sale_time = 0; // 最新上架时间(每次上架都要修改)
		let update_time = 0; // 最后修改时间
		let total_sell_count = initial_sell_count + real_sell_count; // 商品总销量（用户看到的）= 实际总销量 + 商品初始总销量
		// 检测商品名称是否已存在
		let num = await vk.daoCenter.goodsDao.count(countWhereJson);
		if (num > 0) {
			return { code: -1, msg: `商品名称【${name}】不能重复!` };
		}


		let dataJson = {
			// 基础信息
			status,

			name,
			category_ids,
			goods_desc,
			keywords,
			// 图片信息
			goods_thumb,
			goods_banner_imgs,
			// 详情信息
			goods_detail_mode,
			goods_detail_imgs,
			goods_detail_body,
			goods_tags,
			goods_services,
			// 实物商品
			is_free_delivery,
			freight_id,
			// 电子卡券
			exp_time_mode,
			exp_time_range,
			exp_time_rule,
			// 多规格信息
			spec_list, // sku规则组
			// 商品参数信息
			is_on_sale,
			is_new,
			is_best,
			is_hot,
			disable_vip, // 是否禁用会员价
			disable_coupon, // 是否禁用优惠券
			// 购物车规则
			cart_rule, // 购物车规则
			// 商品限购规则
			limit_buy_rule, // 商品限购规则
			// 积分规则
			integral_rule,
			// 其他信息
			initial_sell_count, // 商品初始总销量
			seller_note,
			sort,
			// 计算得出的字段
			stock,
			real_sell_count,
			total_sell_count,
			comment_count,
			view_count,
			on_sale_time,
			update_time,
			// 分销专属字段
			reward_rule
		}

		if (mode === "add") {
			vk.pubfn.objectAssign(dataJson, {
				type,
			});
			// 添加
			_id = await vk.daoCenter.goodsDao.add(dataJson);
		} else {
			// 修改
			res.info = await vk.daoCenter.goodsDao.updateAndReturn({
				whereJson: {
					_id
				},
				dataJson
			});
			if (!res.info) {
				return { code: -1, msg: "修改失败，请重试!" };
			}
		}

		// 批量添加sku信息
		let sku_list_arr = [];
		for (let i in sku_list) {
			let sku = sku_list[i];
			let sku_name = "";
			for (let j = 0; j < sku.sku_name_arr.length; j++) {
				sku_name += sku.sku_name_arr[j];
				if (j < (sku.sku_name_arr.length - 1)) {
					sku_name += " / ";
				}
			}
			let skuIndex = Number(i) + 1;
			sku_list_arr.push({
				_id: `${_id}-${skuIndex}`, // sku规则 商品id-index
				goods_id: _id, // 商品ID
				goods_name: name, // 商品名称（冗余字段）
				image: sku.image || goods_thumb, // sku图片
				sku_name: sku_name, // sku名称
				sku_name_arr: sku.sku_name_arr, // sku名称数组组合
				price: Number(sku.price), // 价格/售价 单位分 100 = 1元
				market_price: Number(sku.market_price), // 市场价（最多保留小数点后2位的正数）(划线价) 单位分 100 = 1元
				stock: Number(sku.stock), // 当前库存数量(最大到 999999)
				weight: Number(sku.weight), //	重量 1 = 1KG
				real_sell_count: 0, // 该规格实际销量
				vip_price_rules: sku.vip_price_rules, // 会员价规则
			});
		}

		if (mode === "update") {
			// 如果是修改，则先删除原先的sku
			await vk.daoCenter.skuDao.del({
				goods_id: _id
			});
		}
		// 添加sku
		await vk.daoCenter.skuDao.adds(sku_list_arr);
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改商品vip价格
	 * @url admin/business/sys.goods.updateVipMoney 前端调用的url参数地址
	 */
	updateVipMoney: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			rules_list = []
		} = data;
		// 需要循环修改
		for (let i = 0; i < rules_list.length; i++) {
			// 参数非空检测
			let {
				_id,
				vip_price_rules
			} = rules_list[i];
			if (vk.pubfn.isNull(_id)) {
				return { code: -1, msg: '参数错误' };
			};
			await vk.daoCenter.skuDao.updateById(_id, {
				vip_price_rules
			});
		};
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改商品自定义分销奖励规则
	 * @url admin/business/sys.goods.updateRewardRule 前端调用的url参数地址
	 */
	updateRewardRule: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id,
			reward_rule
		} = data;
		if (vk.pubfn.isNull(_id)) return { code: -1, msg: "id不能为空" };
		res.info = await vk.daoCenter.goodsDao.updateAndReturn({
			whereJson: {
				_id
			},
			dataJson: {
				reward_rule: _.set(reward_rule)
			}
		});

		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 评论修改商品分类
	 * @url admin/business/sys.goods.updateCategory 前端调用的url参数地址
	 */
	updateCategory: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			type = 1,
				goods_ids,
				category_ids
		} = data;
		if (vk.pubfn.isNull(goods_ids)) {
			return { code: -1, msg: '参数错误' };
		}
		let dataJson = {};
		if (type === 1) {
			// 替换原有分类
			dataJson["category_ids"] = _.set(category_ids);
		} else {
			// 添加指定分类
			dataJson["category_ids"] = _.addToSet({
				$each: category_ids
			});
		}
		res.num = await vk.daoCenter.goodsDao.update({
			whereJson: {
				_id: _.in(goods_ids)
			},
			dataJson
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 获取商品状态分组数量
	 * @url admin/business/sys.goods.getStatusCountGroup 前端调用的url参数地址
	 */
	getStatusCountGroup: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let batchRunRes = await vk.pubfn.batchRun({
			// 主执行函数
			main: [
				async () => {
						return await vk.daoCenter.goodsDao.count({
							status: 1,
							is_on_sale: true
						});
					},
					async () => {
							return await vk.daoCenter.goodsDao.count({
								status: 1,
								is_on_sale: false
							});
						},
						async () => {
								return await vk.daoCenter.goodsDao.count({
									status: 2
								});
							},
							async () => {
								return await vk.daoCenter.goodsDao.count({
									status: 1,
									stock: _.lte(0)
								});
							},
			],
			// 最大并发量,如果设置为1,则会按顺序执行
			concurrency: 10
		});
		res.group = batchRunRes.stack;
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 当前最大的sort
	 * @url admin/business/sys.goods.getMaxSort 前端调用的url参数地址
	 */
	getMaxSort: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let sort = await vk.daoCenter.goodsDao.max({
			fieldName: "sort",
			whereJson: {
				sort: _.gte(0)
			}
		});
		res.sort = sort || 0;
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 商品批量导入
	 * @url admin/business/sys.goods.importGoods 前端调用的url参数地址
	 */
	importGoods: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			base64, // 文件的base64值
			imageMode, // 图片储存方式
		} = data;
		// 加密参数
		let encryptedData = vk.crypto.aes.encrypt({
			data
		});
		// 导入 import-excel 云对象（这里 import-excel 单独1个官方版云对象，是因为 node-xlsx 的npm包太大了，需要独立出来）
		const importExcel = uniCloud.importObject('import-excel');
		res = await importExcel.importGoods(encryptedData);
		return res;
	},
	/**
	 * 模板函数
	 * @url admin/business/sys.goods.test 前端调用的url参数地址
	 */
	test: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------


		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
};

module.exports = cloudObject;
